home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / source / demostuf / vr.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1994-07-25  |  17.3 KB  |  968 lines

  1. program virtual_reality;
  2. {
  3.     Virtual Reality #1
  4.     - by Bjarke Viksφe
  5.     apr 1994
  6.  
  7.   THIS PROGRAM WAS CODED BY BJARKE VIKS0E.
  8.   YOU ARE FREE TO DO WHATEVER YOU WANT WITH THIS PIECE OF CODE.
  9.   E-MAIL ME AT: dat92230@rix02.lyngbyes.dk IN 1994 FOR CHAT AND CODE.
  10.  
  11.     Pass LABYRINT.TXT as parameters (in the RUN/-menu) and make sure that
  12.     the file is in the current directory...
  13.  
  14.     No texture-mapped walls. Could be easily added. Simply store
  15.     some y-values along with colors...
  16.     But the whole concept seem to have been misunderstood. As I
  17.     figure it, Doom and the likes use some devious ray-casting scheme
  18.     to create walls.
  19.     This program uses a much more simplyfied way of making walls. Simply
  20.     rotate all walls. See if they are within eye-range. Paint them one
  21.     by one using painter's-algorithm in reverse (starting with nearest one).
  22.  
  23.     Walls are copied to a buffer and when done, the whole lot is copied
  24.     quickly to the screen. This is actually a great deal faster that doing
  25.     screen-writes at once (because I don't do word-writes I guess!).
  26.  
  27. }
  28.  
  29. {$A+,B-,G+,E+,I+,N-,X+}
  30.  
  31. uses
  32.     DEMOINIT,MOUSE{,TEXT1};
  33.  
  34.  
  35. (*{$DEFINE DEBUG}*)
  36.  
  37. const
  38.     MOUSE_CONTROL = TRUE;
  39.  
  40.     {Plade sizes}
  41.     MAX = 10;
  42.     {Box definitions}
  43.     HEIGHT = 120;
  44.     MIDDLE_X = 160;
  45.     MIDDLE_Y = HEIGHT DIV 2;
  46.     {Colors}
  47.     floor_color = 194;
  48.     sky_color = 195;
  49.     yellow1_color = 190;
  50.     yellow2_color = 191;
  51.     red1_color = 192;
  52.     red2_color = 193;
  53.     {Coord consts}
  54.     MAXZ = 7000;
  55.     BOXX = 150;
  56.     BOXY = 100;
  57.     BOXZ = BOXX;
  58.  
  59. type
  60.     pKasse = ^kassetype;
  61.     kassetype = RECORD
  62.         x,z : integer;
  63.         newx,newz : integer;
  64.         f1,f2,f3,f4 : boolean;
  65.     end;
  66.     kassetabel = array[0..441] of pKasse;
  67.  
  68.     booktabel = array[0..320] of integer; {tabel for book-keeping}
  69.  
  70.     pDispBuffer = ^dispbuffertype;
  71.     dispbuffertype = array[0..WIDTH*HEIGHT] of byte;
  72.  
  73.  
  74. var
  75.     v : word;
  76.     vinkel1,vinkel2 : integer;
  77.     sintabel : array [0..639] of integer;
  78.  
  79.     speedx,speedz : integer;
  80.     worldx,worldz : integer;
  81.     mousex,mousey : integer;
  82.  
  83.     tabel : booktabel;
  84.     paint : booktabel;
  85.     color : booktabel;
  86.  
  87.     plade : array[-MAX..MAX] of string[21];
  88.  
  89.     count : integer; {kasser ialt}
  90.     antal : integer; {kasser tilbage efter beregninger...}
  91.  
  92.     alle_kasser : array[-MAX..MAX,1..22] of pKasse;
  93.     kasser : kassetabel;
  94.     synlige_kasser : kassetabel;
  95.  
  96.     dispbuffer : pDispBuffer;
  97.  
  98. const
  99.     display1 : word = $0000;
  100.     display2 : word = $4000;
  101.     display3 : word = $8000;
  102.  
  103. procedure RotateCoord(x,y,z : integer; VAR rx,ry,rz : integer); forward;
  104. procedure RotateKasse(x,z : integer; VAR rx,rz : integer); forward;
  105. function WhereX(x : integer) : integer; forward;
  106. function WhereZ(z : integer) : integer; forward;
  107.  
  108.  
  109.  
  110. (*------------------------------------------------*)
  111.  
  112. procedure SetPlot(x,y,size,color : integer);
  113. var
  114.     i,j : integer;
  115. begin
  116.     for i:=0 to size do for j:=0 to size do
  117.         SetPixel(display2,x+i,y+j,color);
  118. end;
  119.  
  120. procedure DrawBigHelpScreen;
  121. var
  122.     x,y : integer;
  123.     i,j,k : integer;
  124. begin
  125.     for i:=-MAX to MAX do begin
  126.         for j:=1 to 21 do if plade[i,j]='*' then begin
  127.             x:=160+(i*5);
  128.             y:=82+((j-MAX)*5);
  129.             SetPlot(x,y,4,red2_color);
  130.             SetPlot(x+1,y+1,2,red1_color);
  131.         end;
  132.     end;
  133.     x:=160-((WhereX(-worldz)+1)*5);
  134.     y:=82-(WhereZ(-worldx)*5);
  135.     SetPlot(x+1,y+1,2,yellow1_color);
  136.     SetPlot(x+2,y+2,0,yellow2_color);
  137.  
  138.     Key:=#0;
  139.     while Key=#0 do ;
  140.     Key:=#0;
  141.     SetMousePos(160,100);
  142. end;
  143.  
  144. (*------------------------------------------------*)
  145.  
  146. procedure SystemCheck;
  147. begin
  148.     if NOT MouseDriverPresent then begin
  149.         writeln;
  150.         writeln('ERROR: Needs mouse-driver.');
  151.         writeln;
  152.         halt;
  153.     end;
  154.     if (ParamCount<>1) then begin
  155.         writeln;
  156.         writeln('USAGE: BONUS.EXE <FILENAME OF LABYRINTH-TEXTFILE>');
  157.         writeln;
  158.         halt;
  159.     end;
  160.     if (Test8086<2) then begin
  161.         writeln;
  162.         writeln('ERROR: Needs at least a ''386!');
  163.         writeln;
  164.         halt;
  165.     end;
  166. end;
  167.  
  168.  
  169. procedure SetupSinus;
  170. var
  171.     i : integer;
  172.     v, vadd : real;
  173. begin
  174.     v:=0.0;
  175.     vadd:=(2.0*pi/512.0);
  176.     for i:=0 to 639 do begin
  177.         sintabel[i]:=round(sin(v)*32767);
  178.         v:=v+vadd;
  179.     end;
  180. end;
  181.  
  182. procedure SetColors;
  183. var
  184.     i : integer;
  185. begin
  186.     for i:=0 to 64 do setRGB(i,i,i,i);
  187.     SetRGB(floor_color,13,13,13);
  188.     for i:=0 to (HEIGHT DIV 4) do
  189.         SetRGB(sky_color+i,3,6+(i DIV 1),38+(i DIV 2));
  190.     SetRGB(yellow1_color,58,52,3);
  191.     SetRGB(yellow2_color,63,57,7);
  192.     SetRGB(red1_color,63,7,7);
  193.     SetRGB(red2_color,60,3,3);
  194. end;
  195.  
  196. procedure InitKasser;
  197. var
  198.     tempstr : string;
  199.     fil : text;
  200.     i,j,k : integer;
  201. begin
  202.     {$I-}
  203.     Assign(fil,ParamStr(1));
  204.     Reset(fil);
  205.     {$I+}
  206.     if (IOresult<>0) then begin
  207.         writeln;
  208.         writeln('ERROR: File not found...');
  209.         writeln;
  210.         halt;
  211.     end;
  212.     for i:=-MAX to MAX do begin
  213.         {$I-}
  214.         ReadLn(fil,tempstr);
  215.         {$I+}
  216.         if (IOresult<>0) OR (length(tempstr)<21) then begin
  217.             Close(fil);
  218.             writeln;
  219.             writeln('ERROR: Wrong file format...');
  220.             writeln;
  221.             halt;
  222.         end;
  223.         plade[i]:=tempstr;
  224.     end;
  225.     Close(fil);
  226.  
  227.     count:=0;
  228.     for i:=-MAX to MAX do begin
  229.         k:=1;
  230.         for j:=1 to 21 do
  231.             if (plade[i][j]='*') then begin
  232.                 new(alle_kasser[i,k]);
  233.                 with (alle_kasser[i,k]^) do begin
  234.                     z:=(i*BOXZ*2)+BOXZ;
  235.                     x:=((j-(MAX+1))*BOXX*2)+BOXX;
  236.                     f1:=TRUE; f2:=TRUE; f3:=TRUE; f4:=TRUE;
  237.                     if (i<>-MAX) AND (plade[i-1][j]='*') then f1:=FALSE;
  238.                     if (j<>1) AND (plade[i][j-1]='*') then f2:=FALSE;
  239.                     if (i<>MAX) AND (plade[i+1][j]='*') then f3:=FALSE;
  240.                     if (j<>21) AND (plade[i][j+1]='*') then f4:=FALSE;
  241.                 end;
  242.                 inc(count);
  243.                 inc(k);
  244.             end;
  245.         alle_kasser[i,k]:=NIL;
  246.     end;
  247.     dec(count);
  248. end;
  249.  
  250.  
  251. procedure InitDemo;
  252. var
  253.     i : integer;
  254. begin
  255.     new(dispbuffer);
  256.     ClearWholeScreen;
  257.     SetColors;
  258.     SetupSinus;
  259.  
  260.     InitMouse;
  261.     MouseOff;
  262.     SetMousePos(160,100);
  263.  
  264.     i:=-MAX;
  265.     while (plade[i,2]<>' ') do inc(i);
  266.     worldx:=-i*BOXX*2;
  267.     dec(worldx,BOXX);
  268.     worldz:=(-MAX)*BOXX*2;
  269.     inc(worldz,BOXX);
  270.  
  271.     v:=270;
  272.     speedx:=-18;
  273.     speedz:=0;
  274. end;
  275.  
  276. procedure UninitDemo;
  277. var
  278.     i,j : integer;
  279. begin
  280.     for i:=-MAX to MAX do begin
  281.         j:=1;
  282.         while (alle_kasser[i,j]<>NIL) do begin
  283.             Dispose(alle_kasser[i,j]);
  284.             inc(j);
  285.         end;
  286.     end;
  287.     Dispose(dispbuffer);
  288. end;
  289.  
  290.  
  291. (*------------------------------------------------*)
  292.  
  293. procedure SwapDisplay;
  294. var
  295.     temp : word;
  296. begin
  297.     temp:=display3;
  298.     display3:=display2;
  299.     display2:=display1;
  300.     display1:=temp;
  301.     SetAddress(Ptr(SEGA000,display2));
  302. end;
  303.  
  304.  
  305. (*------------------------------------------------*)
  306. (*-          MOVE PLAYER AROUND A BIT            -*)
  307. (*------------------------------------------------*)
  308.  
  309. function WhereX(x : integer) : integer;
  310. begin
  311.     WhereX:=longdiv(-x+(MAX*BOXX*2),BOXX*2)-MAX;
  312. end;
  313.  
  314. function WhereZ(z : integer) : integer;
  315. begin
  316.     WhereZ:=longdiv(-z+(MAX*BOXX*2),BOXX*2)-MAX;
  317. end;
  318.  
  319. procedure MovePlayer;
  320. var
  321.     x,y,z : integer;
  322.     newWhereX, newWhereZ : integer;
  323.     oldworldx, oldworldz : integer;
  324.     cx,cz : longint;
  325.     lb,rb : boolean;
  326. begin
  327.     fillchar(paint,sizeof(paint),0);
  328.  
  329.     if (MOUSE_CONTROL) then begin
  330.         MouseInfo(x,y,lb,rb);
  331.         SetMousePos(160,100);
  332.         x:=(x-160) DIV 4;
  333.         v:=(v+x) AND 511;
  334.     end
  335.     else v:=(v+2) AND 511;
  336.  
  337.     vinkel1:=sintabel[v];
  338.     vinkel2:=sintabel[v+128];
  339.  
  340.     if (MOUSE_CONTROL) AND (rb OR lb) then begin
  341.         RotateKasse(speedx,speedz,x,z);
  342.         oldworldx:=worldx;
  343.         oldworldz:=worldz;
  344.         inc(worldx,z);
  345.         inc(worldz,x);
  346.         newWhereX:=WhereX(worldz);
  347.         newWhereZ:=WhereZ(worldx);
  348.         {bumped into a wall?}
  349.         if (plade[WhereX(worldz),newWhereZ+MAX+1]='*') then begin
  350.             worldx:=oldworldx;
  351.             worldz:=oldworldz;
  352.         end
  353.         else
  354.         if (plade[WhereX(worldz-40),newWhereZ+MAX+1]='*') then begin
  355.             worldx:=oldworldx;
  356.             worldz:=oldworldz;
  357.         end
  358.         else
  359.         if (plade[WhereX(worldz+40),newWhereZ+MAX+1]='*') then begin
  360.             worldx:=oldworldx;
  361.             worldz:=oldworldz;
  362.         end
  363.         else
  364.         if (plade[newWhereX,WhereZ(worldx-40)+MAX+1]='*') then begin
  365.             worldx:=oldworldx;
  366.             worldz:=oldworldz;
  367.         end
  368.         else
  369.         if (plade[newWhereX,WhereZ(worldx+40)+MAX+1]='*') then begin
  370.             worldx:=oldworldx;
  371.             worldz:=oldworldz;
  372.         end;
  373.     end;
  374. end;
  375.  
  376.  
  377. (*------------------------------------------------*)
  378. (*-             ROTATE ALL THAT STUFF            -*)
  379. (*------------------------------------------------*)
  380.  
  381. procedure RotateKasse(x,z : integer; VAR rx,rz : integer); assembler;
  382. asm
  383.     mov    ax,x
  384.     mov    cx,ax
  385.     imul    WORD PTR vinkel2
  386.     add    ax,ax
  387.     adc    dx,dx
  388.     mov    bx,dx
  389.     mov    ax,z
  390.     imul    WORD PTR vinkel1
  391.     add    ax,ax
  392.     adc    dx,dx
  393.     sub   bx,dx
  394.     les    di,rx
  395.     mov    [es:di],bx
  396.     mov    ax,cx
  397.     imul    WORD PTR vinkel1
  398.     add    ax,ax
  399.     adc    dx,dx
  400.     mov    bx,dx
  401.     mov    ax,z
  402.     imul    WORD PTR vinkel2
  403.     add    ax,ax
  404.     adc    dx,dx
  405.     add    bx,dx
  406.     les    di,rz
  407.     mov    [es:di],bx
  408. end;
  409.  
  410. procedure RotateCoord(x,y,z : integer; VAR rx,ry,rz : integer); assembler;
  411. asm
  412.     mov    ax,x
  413.     mov    cx,ax
  414.     imul    WORD PTR vinkel2
  415.     add    ax,ax
  416.     adc    dx,dx
  417.     mov    bx,dx
  418.     mov    ax,z
  419.     imul    WORD PTR vinkel1
  420.     add    ax,ax
  421.     adc    dx,dx
  422.     sub   bx,dx
  423.     les    di,rx
  424.     mov    [es:di],bx
  425.     mov    ax,cx
  426.     imul    WORD PTR vinkel1
  427.     add    ax,ax
  428.     adc    dx,dx
  429.     mov    bx,dx
  430.     mov    ax,z
  431.     imul    WORD PTR vinkel2
  432.     add    ax,ax
  433.     adc    dx,dx
  434.     add    bx,dx
  435.     les    di,rz
  436.     mov    [es:di],bx
  437.     les    di,ry
  438.     mov    ax,y
  439.     mov    [es:di],ax
  440. end;
  441.  
  442.  
  443. (*------------------------------------------------*)
  444. (*-                 CALC STUFF                   -*)
  445. (*------------------------------------------------*)
  446.  
  447. procedure CalcSlope(x1,y1,z1,x2,y2,z2 : integer; color : integer);
  448. const
  449.     zcut = 35;
  450. var
  451.     n : integer;
  452.     temp : integer;
  453.     y,dely : longint;
  454.     swapped : boolean;
  455. begin
  456.     {cut z-coord}
  457.     swapped:=FALSE;
  458.     if (z1>z2) then asm
  459.         mov    ax,x1
  460.         xchg    ax,x2
  461.         mov   x1,ax
  462.         mov    ax,y1
  463.         xchg    ax,y2
  464.         mov   y1,ax
  465.         mov    ax,z1
  466.         xchg    ax,z2
  467.         mov    z1,ax
  468.         mov    swapped,TRUE
  469.     end;
  470.     if (z2<ZCUT) then exit;
  471.     if (z1<=ZCUT) then begin
  472.         z1:=z2-z1;
  473.         temp:=ZCUT-z2;
  474.         if (z1=0) then z1:=1;
  475.         x1:=longdiv(longmul(temp,x2-x1),z1)+x2;
  476.         y1:=longdiv(longmul(temp,y2-y1),z1)+y2;
  477.         z1:=ZCUT;
  478.     end;
  479.  
  480.     {calc perspektive}
  481.     asm
  482.         mov    cx,z1            {(x1 shl 8) DIV z1}
  483.         mov    ax,x1
  484.         cwd
  485.         mov    dl,ah
  486.         mov    ah,al
  487.         xor    al,al
  488.         idiv    cx
  489.         add    ax,MIDDLE_X
  490.         mov    x1,ax
  491.         mov    ax,y1            {(y1 shl 8) DIV z1}
  492.         cwd
  493.         mov    dl,ah
  494.         mov    ah,al
  495.         xor    al,al
  496.         idiv    cx
  497.         mov    y1,ax
  498.  
  499.         mov    cx,z2
  500.         mov    ax,x2
  501.         cwd
  502.         mov    dl,ah
  503.         mov    ah,al
  504.         xor    al,al
  505.         idiv    cx
  506.         add    ax,MIDDLE_X
  507.         mov    x2,ax
  508.         mov    ax,y2
  509.         cwd
  510.         mov    dl,ah
  511.         mov    ah,al
  512.         xor    al,al
  513.         idiv    cx
  514.         mov    y2,ax
  515.     end;
  516.  
  517.     if (swapped) then asm
  518.         mov    ax,x1
  519.         xchg    ax,x2
  520.         mov   x1,ax
  521.         mov    ax,y1
  522.         xchg    ax,y2
  523.         mov   y1,ax
  524.         {z-coord is not swapped this time... no longed needed!}
  525.     end;
  526.  
  527.     {is the face is shown at all...}
  528.     if (x1>x2) then exit;
  529.     n:=x2-x1;
  530.     {cut borders if nessesary}
  531.     if (x1>=320) OR (x2<=0) OR (n<1) then exit;
  532.     if (x1<0) AND (x1<>x2) then begin
  533.         inc(n,x1);
  534.         y1:=-longdiv(longmul(y1-y2,x2),(x1-x2))+y2;
  535.         x1:=0;
  536.     end;
  537.     if (x2>=320) AND (x2<>x1) then begin
  538.         n:=(320-x1);
  539.         y2:=longdiv(longmul(y2-y1,319-x1),(x2-x1))+y1;
  540.         x2:=319;
  541.     end;
  542.     {prepare calc slope...}
  543.     if (n<1) then exit;
  544.     dely := (y2-y1) * ($10000 DIV (n));
  545.     y := y1 * (1 shl 16);
  546.     asm
  547.         mov    ax,ds
  548.         mov    es,ax
  549.         lea    di,tabel
  550.         mov    si,n
  551.         mov    ax,WORD PTR y+2
  552.         mov    dx,WORD PTR y
  553.         mov    cx,WORD PTR dely
  554.         mov    bx,WORD PTR dely+2
  555.         cld
  556. @loop1:
  557.         add    dx,cx
  558.         adc    ax,bx
  559.         stosw
  560.         dec    si
  561.         jnz    @loop1
  562.  
  563.  
  564.         mov    ax,ds
  565.         mov    es,ax
  566.         lea    si,paint
  567.         mov    ax,x1
  568.         shl    ax,1
  569.         add    si,ax
  570.         lea    di,tabel
  571.         mov    bx,color
  572.         mov    dx,2
  573.         mov    cx,n
  574. @insert:
  575.         lodsw
  576.         and    ax,ax
  577.         jnz    @occupied
  578.         mov    ax,[di]
  579.         cmp    ax,1
  580.         jge    @below
  581.         mov    ax,1
  582. @below:
  583.         cmp    ax,MIDDLE_Y
  584.         jle    @above
  585.         mov    ax,MIDDLE_Y
  586. @above:
  587.         mov    [si-2],ax {insert height}
  588.         mov    [si+TYPE(booktabel)-2],bx {insert color}
  589. @occupied:
  590.         add    di,dx
  591.         loop    @insert
  592.     end;
  593. end;
  594.  
  595.  
  596. procedure SortKasseListe(antal : integer);
  597. {highly optimized, eh?}
  598. var
  599.     j : integer;
  600.     done : boolean;
  601. begin
  602.     j:=0;
  603.     asm
  604. @sortloop1:
  605.         lea    bx,synlige_kasser
  606.         mov    done,TRUE
  607.         mov    cx,antal
  608.         sub    cx,j
  609.         jcxz    @donesorting
  610.  
  611.         les    si,[bx]
  612.         mov    dx,[es:si+kassetype.newz]
  613. @sortloop2:
  614.         mov    di,dx
  615.         add    bx,TYPE pKasse
  616.         les    si,[bx]
  617.         mov    dx,[es:si+kassetype.newz]
  618.         cmp    di,dx
  619.         jle    @noswap
  620.  
  621.         mov    ax,es
  622.         xchg    si,[bx-4]
  623.         xchg    ax,[bx-2]
  624.         mov    [bx],si
  625.         mov    [bx+2],ax
  626.         mov    es,ax
  627.         mov    dx,di
  628.         mov    done,FALSE
  629. @noswap:
  630.         dec    cx
  631.         jnz    @sortloop2
  632.         inc    j
  633.         cmp    done,FALSE
  634.         je        @sortloop1
  635. @donesorting:
  636.     end;
  637. end;
  638.  
  639.  
  640. (*------------------------------------------------*)
  641. (*-             DRAW ENTIRE SCREEN               -*)
  642. (*------------------------------------------------*)
  643.  
  644. procedure DrawScreen(i : integer); assembler;
  645. var
  646.     temp,lowheight,
  647.     n : integer;
  648. asm
  649.     push    ds
  650.  
  651.     {fill out bitplane with colors}
  652.     mov    ax,ds
  653.     mov    es,ax
  654.     lea    di,paint
  655.     mov    ax,i
  656.     shl    ax,1
  657.     add    di,ax
  658.  
  659.     lds    si,dispbuffer
  660.     mov    dx,WIDTH*2
  661.     mov    n,80
  662.     cld
  663. @loop:
  664.     push    si
  665.     mov    ax,[es:di]
  666.  
  667.     {fill sky}
  668.     mov    temp,ax
  669.     mov    cx,MIDDLE_Y
  670.     sub    cx,ax
  671.     mov    Lowheight,cx
  672.     jcxz    @no1
  673.     mov    al,SKY_COLOR
  674.     mov    bx,$0001
  675.     test    cx,1
  676.     jz        @calcfill1
  677.     mov    [si],al
  678.     add    si,WIDTH
  679.     mov    bx,$0100
  680.     inc    al
  681.     dec    cx
  682.     jcxz    @no1
  683. @calcfill1:
  684.     shr    cx,1
  685. @fill1:
  686.     mov    [si],al
  687.     add    al,bl
  688.     mov    [si+WIDTH],al
  689.     add    al,bh
  690.     add    si,dx
  691.     loop    @fill1
  692. @no1:
  693.  
  694.     {fill walls}
  695.     mov    cx,temp
  696.     shl    cx,1
  697.     jcxz    @no2
  698.     mov    al,[es:di+TYPE(booktabel)]
  699.     test    cx,3
  700.     jz        @calcfill2
  701.     mov    ah,cl
  702.     and    ah,3
  703.     mov    [si],al
  704.     add    si,WIDTH
  705.     dec    cx
  706.     dec    ah
  707.     jz        @calcfill2
  708.     mov    [si],al
  709.     add    si,WIDTH
  710.     dec    cx
  711.     dec    ah
  712.     jz        @calcfill2
  713.     mov    [si],al
  714.     add    si,WIDTH
  715.     dec    cx
  716. @calcfill2:
  717.     shr    cx,2
  718.     jcxz    @no2
  719.     mov    bx,WIDTH*3
  720.     mov    dx,WIDTH*4
  721. @fill2:
  722.     mov    [si],al
  723.     mov    [si+(WIDTH)],al
  724.     mov    [si+(WIDTH*2)],al
  725.     mov    [si+bx],al
  726.     add    si,dx
  727.     loop    @fill2
  728.     mov    dx,WIDTH*2
  729. @no2:
  730.  
  731.     {fill floor}
  732.     mov    cx,LowHeight
  733.     jcxz    @no3
  734.     mov    al,FLOOR_COLOR
  735.     mov    bx,WIDTH
  736.     test    cx,1
  737.     jz        @calcfill3
  738.     mov    [si],al
  739.     add    si,bx
  740.     dec    cx
  741.     jcxz    @no3
  742. @calcfill3:
  743.     shr    cx,1
  744. @fill3:
  745.     mov    [si],al
  746.     mov    [si+bx],al
  747.     add    si,dx
  748.     loop    @fill3
  749. @no3:
  750.  
  751. @done:
  752.     add    di,8
  753.     pop    si
  754.     inc    si
  755.     dec    n
  756.     jnz    @loop
  757.  
  758.  
  759.     {copy this bitplane to screen}
  760.     mov    ax,SEG @DATA
  761.     mov    ds,ax
  762.     mov    es,SEGA000
  763.     mov    di,display1
  764.     add    di,WIDTH*30 {window offset}
  765.     lds    si,dispbuffer
  766.     mov    cx,(WIDTH*HEIGHT)/4
  767.     rep; DB LONG; movsw;
  768.     pop    ds
  769. end;
  770.  
  771.  
  772. (*------------------------------------------------*)
  773. (*-             SELECT VISIBLE KASSER            -*)
  774. (*------------------------------------------------*)
  775.  
  776. procedure CopyKasser1(p : pointer); assembler;
  777. {get kasser in current row and rows beside}
  778. asm
  779.     push    ds
  780.     mov    ax,ds
  781.     mov    es,ax
  782.     lea    di,kasser
  783.     mov    ax,antal
  784.     shl    ax,1
  785.     shl    ax,1
  786.     add    di,ax
  787.     mov    bx,antal
  788.     lds    si,p
  789.     cld
  790. @copy:
  791.     lodsw
  792.     mov    dx,ax
  793.     lodsw
  794.     and    ax,ax
  795.     jnz    @docopy
  796.     and    dx,dx
  797.     jz        @nomore
  798. @docopy:
  799.     xchg    ax,dx
  800.     stosw
  801.     mov    ax,dx
  802.     stosw
  803.     inc    bx
  804.     jmp    NEAR PTR @copy
  805. @nomore:
  806.     mov    antal,bx
  807.     pop    ds
  808. end;
  809.  
  810. procedure CopyKasser2(p : pointer; zmin,zmax : integer); assembler;
  811. {get kasser in current coloum and the ones beside it}
  812. asm
  813.     push    ds
  814.     mov    ax,ds
  815.     mov    es,ax
  816.     lea    di,kasser
  817.     mov    ax,antal
  818.     shl    ax,1
  819.     shl    ax,1
  820.     add    di,ax
  821.     mov    cx,zmin
  822.     lds    si,p
  823.     mov    cx,ds    {get pointer-segment}
  824.     cld
  825. @copy:
  826.     lodsw
  827.     mov    bx,ax
  828.     lodsw
  829.     and    ax,ax
  830.     jnz    @docopy
  831.     and    bx,bx
  832.     jz        @nomore
  833. @docopy:
  834.     mov    ds,ax
  835.     mov    dx,[bx+kassetype.x]
  836.     cmp    dx,zmin
  837.     jle    @notthis
  838.     cmp    dx,zmax
  839.     jge    @notthis
  840.     xchg    ax,bx
  841.     stosw
  842.     mov    ax,bx
  843.     stosw
  844.     inc    es:antal
  845. @notthis:
  846.     mov    ds,cx
  847.     jmp    NEAR PTR @copy
  848. @nomore:
  849.     pop    ds
  850. end;
  851.  
  852. procedure GetSomeKasser;
  853. var
  854.     x,x_min,x_max,
  855.     z,z_min,z_max : integer;
  856.     i,j : integer;
  857. begin
  858.     antal:=0;
  859.  
  860.     x:=WhereZ(worldz);
  861.     x_min:=x-2;
  862.     x_max:=x+2;
  863.     for i:=-MAX to MAX do
  864.         if (i>=x_min) AND (i<=x_max) then CopyKasser1(@alle_kasser[i,1]);
  865.  
  866.     z:=-worldx;
  867.     z_min:=z-(BOXX*4)-1;
  868.     z_max:=z+(BOXX*4)-1;
  869.     for i:=-MAX to MAX do if (i<x_min) OR (i>x_max) then
  870.         CopyKasser2(@alle_kasser[i,1],z_min,z_max);
  871.  
  872.     dec(antal);
  873. end;
  874.  
  875.  
  876. procedure GetSomeLessKasser;
  877. var
  878.     i,j : integer;
  879. begin
  880.     j:=-1;
  881.     for i:=0 to antal do with kasser[i]^ do begin
  882.         RotateKasse(x+worldx,z+worldz,newx,newz);
  883.         if (newz>-BOXX) AND (newx>-3200) AND (newx<3200) then begin
  884.             inc(j);
  885.             synlige_kasser[j]:=kasser[i];
  886.         end;
  887.     end;
  888.     antal:=j;
  889. end;
  890.  
  891.  
  892. procedure DrawEmAll;
  893. var
  894.     i : integer;
  895.     color : integer;
  896.     x1,y1,z1,
  897.     x2,y2,z2,
  898.     x3,y3,z3,
  899.     x4,y4,z4 : integer;
  900. begin
  901.     for i:=0 to antal do with synlige_kasser[i]^ do begin
  902.         RotateCoord(worldx+x-BOXX,BOXY,worldz+z-BOXZ, x1,y1,z1);
  903.         RotateCoord(worldx+x+BOXX,BOXY,worldz+z-BOXZ, x2,y2,z2);
  904.         RotateCoord(worldx+x+BOXX,BOXY,worldz+z+BOXZ, x3,y3,z3);
  905.         RotateCoord(worldx+x-BOXX,BOXY,worldz+z+BOXZ, x4,y4,z4);
  906.         color:=longdiv(MAXZ-newz,128);
  907.         if (f1) then CalcSlope(x1,y1,z1,x2,y2,z2,color);
  908.         if (f4) then CalcSlope(x2,y2,z2,x3,y3,z3,color);
  909.         if (f3) then CalcSlope(x3,y3,z3,x4,y4,z4,color);
  910.         if (f2) then CalcSlope(x4,y4,z4,x1,y1,z1,color);
  911.     end;
  912. end;
  913.  
  914. (*------------------------------------------------*)
  915.  
  916.  
  917. procedure RunOnce;
  918. label
  919.     none;
  920. var
  921.     i : integer;
  922. begin
  923.     SwapDisplay;
  924.     while retraces=0 do ;
  925.     retraces:=0;
  926. {$IFDEF DEBUG}
  927.     i:=retraces;
  928.     while i=retraces do ;
  929.     SetRGB(0,30,0,0);
  930. {$ENDIF}
  931.     MovePlayer;
  932.  
  933.     GetSomeKasser;
  934.     if (antal<0) then goto none;
  935.     GetSomeLessKasser;
  936.     if (antal<0) then goto none;
  937.     SortKasseListe(antal);
  938.     DrawEmAll;
  939. none:
  940.     for i:=0 to 3 do begin
  941.         SetBitplanes(1 shl i);
  942.         DrawScreen(i);
  943.     end;
  944.  
  945.     if (Key='H') then DrawBigHelpScreen;
  946.     if (Key in ['1'..'9']) then speedx:=-((ord(Key)-48) shl 2);
  947.  
  948. {$IFDEF DEBUG}
  949.     SetRGB(0,0,0,0);
  950. {$ENDIF}
  951. end;
  952.  
  953. begin
  954.     SystemCheck;
  955.     InitKasser;
  956.     {IntroText};
  957.     OpenScreen;
  958.     Screen_Off;
  959.     InitDemo;
  960.     SetAllInterrupts;
  961.     Screen_On;
  962.     repeat RunOnce until Key='e';
  963.     RestoreAllInterrupts;
  964.     UninitDemo;
  965.     CloseScreen;
  966. end.
  967.  
  968.